import React, { useState, useEffect, useRef, useImperativeHandle, forwardRef, ElementRef, useMemo } from 'react';
import { Form, Input, Select, Radio, notification, Modal, Loading } from '@block/plug';
import { $fetch } from '@block/utils';
import { ParkerRichText } from '@src/components';
import { EmpSelect } from '@src/aud-sys-component';
import { getUUid, AutoSave, commonBeforeunload } from '@src/utils';
import { AuditAppendix, AuditProblemProgress, AuditFindingGroup } from './elements';
import {
	CONCLUSION_MAX_LENGTH,
	CONCLUSION_TEXT,
	OVERVIEW_MAX_LENGTH,
	OVERVIEW_TEXT,
	SUMMARY_MAX_LENGTH,
	SUMMARY_TEXT,
	AUDIT_CONCLUSION_MOBILE_MAX_LENGTH,
	AUDIT_CONCLUSION_MOBILE_TEXT,
} from './constant';
import { AuditFindingsItem, AuditNotice, IssueFindings, ReportDetail } from './types';
import './index.scss';
import Url from './url';

interface Props {
	projectData: AuditProjectDetailData;
	pageMode: PageMode;
	setBtnLoading?: React.Dispatch<React.SetStateAction<boolean>>;
	handleReportMode: (mode: PageMode) => void;
}

interface Handle {
	saveDraft: (successCallback?: () => void) => void;
	saveSubmit: (successCallback?: () => void) => Promise<void>;
	cancel: (successCallback?: () => void) => void;
}

const POP_LAYER = {
	getContainer: (): HTMLElement => document.querySelector('.project-detail-report') || document.body,
};

/** 自动保存实例 */
const autoSaveInst = new AutoSave();

/**
 * 审计项目管理详情-审计报告
 */

const ProjectDetailReport = forwardRef<Handle, Props>((props, ref) => {
	const { projectData, pageMode, setBtnLoading, handleReportMode } = props;

	const [loading, setLoading] = useState(false);
	/** 审批报告等级下拉 */
	const [gradeList, setGradeList] = useState<SelectOption[]>([]);
	/** 风险等级下拉 */
	const [riskGradeList, setRiskGradeList] = useState<SelectOption[]>([]);
	/** 详情表单Form Ref */
	const formRef = useRef<Form>();
	/** 审计项目概述富文本实例 */
	const overviewRichTextRef = useRef<ElementRef<typeof ParkerRichText>>();
	/** 整改进度ref */
	const progressRef = useRef<ElementRef<typeof AuditProblemProgress>>();
	/** 审计发现详述Ref */
	const findingsRef = useRef<ElementRef<typeof AuditFindingGroup>>();
	/** 附录Ref */
	const appendixRef = useRef<ElementRef<typeof AuditAppendix>>();
	/** 自动保存对比数据 */
	const autoSaveData = useRef('');

	const mode: Mode = useMemo(() => {
		if (['create', 'edit'].includes(pageMode)) return 'edit';
		return 'view';
	}, [pageMode]);

	/** 页面ID参数 */
	const pageParams = { itemNo: projectData?.itemNo, tenantId: projectData?.tenantId };

	/** 新建报告时默认填充初始数据 */
	const handleCreateInit = async () => {
		try {
			const [noticeRes, findingsRes] = await Promise.all([
				$fetch<AuditNotice>(Url.getNoticeDetail, pageParams),
				$fetch<IssueFindings[]>(Url.queryProblemList, pageParams),
			]);
			const { noticeSendMemberList, needKnownEmpList } = noticeRes ?? {};
			const auditProblemList: Partial<AuditFindingsItem>[] = findingsRes?.map((finding) => {
				const { issueBriefDesc, issueDesc, riskLevel, auditRecommend, rectifyList } = finding ?? {};
				return {
					problemId: getUUid('string') as string,
					riskLevel,
					auditRecommend,
					title: issueBriefDesc,
					problemDescAndRiskAnalyze: issueDesc,
					businessFeedbackList: rectifyList,
				};
			});
			if (auditProblemList?.length === 0) auditProblemList.push({ problemId: getUUid('string') as string });
			formRef.current?.setAllFieldsValue({
				noticeSendMemberList,
				needKnownEmpList,
				auditConclusion: CONCLUSION_TEXT,
				problemAndProgressList: [{ problemAndProgressId: getUUid('string') }],
				auditProblemDetailList: [{ auditProblemGroupId: getUUid('string'), auditProblemList }],
			});
		} catch (err) {
			formRef.current?.setAllFieldsValue({
				auditConclusion: CONCLUSION_TEXT,
				problemAndProgressList: [{ problemAndProgressId: getUUid('string') }],
				auditProblemDetailList: [
					{ auditProblemGroupId: getUUid('string'), auditProblemList: [{ problemId: getUUid('string') }] },
				],
			});

			throw err;
		}
	};

	/** 获取报告详情，若后端无数据返回，则当前为创建报告 */
	const getReportData = async () => {
		setLoading(true);
		try {
			const res = await $fetch<ReportDetail>(Url.getReportDetail, pageParams);
			if (res) {
				formRef.current?.setAllFieldsValue(res);
				// 下层Form Item有数据处理，直接get拿不到最新值
				window.setTimeout(() => {
					autoSaveData.current = JSON.stringify(formRef.current?.getFieldsValue());
				}, 0);
			}
		} finally {
			setLoading(false);
		}
	};

	/** 获取审计报告等级下拉 */
	const getGradeList = async () => {
		const res = await $fetch(Url.queryReportLevelList);
		setGradeList(res);
	};

	/** 风险等级等级下拉 */
	const getRiskGradeList = async () => {
		const res = await $fetch(Url.queryRiskLevelList);
		setRiskGradeList(res);
	};

	/** 报告所有表单校验事件 */
	const handleValidate = () => {
		const formValidate = formRef.current?.validateFields();
		const progressValidate = progressRef.current?.onValidate();
		const findingsValidate = findingsRef.current?.onValidate();
		const appendixValidate = appendixRef.current?.onValidate();
		return formValidate && progressValidate && findingsValidate && appendixValidate;
	};

	/** 自动保存草稿事件 */
	const handleAutoSave = async (savePageMode: PageMode) => {
		const url = savePageMode === 'create' ? Url.addReport : Url.editReport;
		const formData = formRef.current?.getFieldsValue();

		// 当为自动保存，且值没有改变，不请求
		if (autoSaveData.current === JSON.stringify(formData)) return;

		autoSaveInst?.stop();
		setBtnLoading(true);
		try {
			autoSaveData.current = JSON.stringify(formData);
			const res = await $fetch(url, { ...pageParams, ...formData });
			if (res) {
				handleReportMode('edit');
				autoSaveInst?.start(() => handleAutoSave('edit'));
			}
		} finally {
			setBtnLoading(false);
		}
	};

	/**
	 * 保存草稿
	 * @param successCallback 成功后回调
	 */
	const handleSave = async (successCallback?: () => void) => {
		const url = pageMode === 'create' ? Url.addReport : Url.editReport;
		const formData = formRef.current?.getFieldsValue();
		setBtnLoading(true);
		try {
			autoSaveInst?.stop();
			const res = await $fetch(url, { ...pageParams, ...formData });
			if (res) {
				notification.success({ title: '成功', message: '操作成功' });
				successCallback?.();
			}
		} catch (err) {
			autoSaveInst?.start(() => handleAutoSave(pageMode));
			throw err;
		} finally {
			autoSaveData.current = JSON.stringify(formData);
			setBtnLoading(false);
		}
	};

	/**
	 * 保存草稿事件，保存前校验填写内容
	 * @param successCallback 成功后回调
	 */
	const handleBeforeSave = (successCallback?: () => void) => {
		const validate = handleValidate();
		autoSaveInst?.stop();
		if (validate) handleSave(successCallback);
		else {
			Modal.warning({
				title: '确定保存草稿？',
				message: '当前存在内容填写不规范的情况，请确认是否保存',
				okText: '确定保存',
				okBtnProps: { type: 'primary', style: { minWidth: 80 } },
				cancelText: '暂不保存',
				cancelBtnProps: { style: { minWidth: 80 } },
				onOk: () => {
					handleSave(successCallback);
				},
				onCancel: () => {
					autoSaveInst?.start(() => handleAutoSave(pageMode));
				},
			});
		}
	};

	/**
	 * 保存提交事件
	 * @param successCallback 成功后回调
	 */
	const handleSubmit = async (successCallback?: () => void) => {
		if (handleValidate()) {
			const url = pageMode === 'create' ? Url.addAndSubmitReport : Url.editAndSubmitReport;
			const formData = formRef.current?.getFieldsValue();
			setBtnLoading(true);
			try {
				autoSaveInst?.stop();
				const res = await $fetch(url, { ...pageParams, ...formData });
				if (res) {
					notification.success({ title: '成功', message: '操作成功' });
					successCallback?.();
				}
			} catch (err) {
				autoSaveInst?.start(() => handleAutoSave(pageMode));
				throw err;
			} finally {
				setBtnLoading(false);
				autoSaveData.current = JSON.stringify(formData);
			}
		}
	};

	/**
	 * 取消编辑事件
	 * @param successCallback 成功后回调
	 */
	const handleCancel = (successCallback?: () => void) => {
		if (formRef.current?.getTouchedFields()?.length > 0) {
			autoSaveInst?.stop();
			Modal.warning({
				title: '确定退出编辑？',
				message: '退出后，不会保存当前数据。',
				okText: '继续编辑',
				okBtnProps: { type: 'primary', style: { minWidth: 80 } },
				cancelText: '退出编辑',
				cancelBtnProps: { style: { minWidth: 80 } },
				onCancel: () => {
					if (pageMode === 'create') {
						formRef.current?.setAllFieldsValue({});
						successCallback?.();
					} else {
						successCallback?.();
					}
				},
				onOk: () => {
					autoSaveInst?.start(() => handleAutoSave(pageMode));
				},
			});
		} else if (pageMode === 'create') {
			formRef.current?.setAllFieldsValue({});
			successCallback?.();
		} else {
			successCallback?.();
		}
	};

	const handleBeforeunload = (e) => commonBeforeunload(e, () => formRef.current?.getTouchedFields()?.length > 0);

	useEffect(() => {
		if (projectData) {
			if (pageMode === 'create') {
				handleCreateInit();
			} else {
				getReportData();
			}
		}
	}, [projectData, pageMode]);

	useEffect(() => {
		if (mode === 'view') {
			formRef.current?.clearTouchedFields();
			formRef.current?.clearValidateStatus();
			autoSaveInst?.stop();
		} else if (projectData) {
			autoSaveInst?.start(() => handleAutoSave(pageMode));
		}
	}, [projectData, mode]);

	useEffect(() => {
		getGradeList();
		getRiskGradeList();

		window.addEventListener('beforeunload', handleBeforeunload);

		return () => {
			autoSaveInst?.stop();
			window.removeEventListener('beforeunload', handleBeforeunload);
		};
	}, []);

	useImperativeHandle(ref, () => ({
		saveDraft: handleBeforeSave,
		saveSubmit: handleSubmit,
		cancel: handleCancel,
	}));

	const renderBaseInfoForm = () => {
		return (
			<>
				<Form.Title>基本信息</Form.Title>
				<Form.Item
					formItemKey="noticeSendMemberList"
					label="发送对象："
					rules={[
						{ required: true, message: '请选择发送对象', type: 'array' },
						{
							validator: (config, value, callback: (str?: string) => void) => {
								if (value?.length > 50) callback('最多可选50人');
								else callback();
							},
						},
					]}
				>
					<EmpSelect
						toFormItem
						mode={mode}
						placeholder="请输入MIS号进行检索（最多可选50人）"
						popLayer={{ getContainer: () => document.querySelector('.project-detail-content') || document.body }}
					/>
				</Form.Item>
				<Form.Item
					formItemKey="needKnownEmpList"
					label="抄送对象："
					rules={[
						{ required: true, message: '请选择抄送对象', type: 'array' },
						{
							validator: (config, value, callback: (str?: string) => void) => {
								if (value?.length > 50) callback('最多可选50人');
								else callback();
							},
						},
					]}
				>
					<EmpSelect
						toFormItem
						mode={mode}
						placeholder="请输入MIS号进行检索（最多可选50人）"
						popLayer={{ getContainer: () => document.querySelector('.project-detail-content') || document.body }}
					/>
				</Form.Item>
				<Form.Item formItemKey="needKnowControlTeamList" label="抄送内控组：">
					{({ value: needKnowControlTeamListValue }) => {
						if (mode === 'edit' || needKnowControlTeamListValue?.length > 0) {
							return (
								<Select
									toFormItem
									popLayer={POP_LAYER}
									placeholder="请选择内控组"
									keyField="code"
									labelField="name"
									multiple
									filterable={false}
									onFetchData={() => {
										return $fetch(Url.queryControlTeamList, {
											tenantId: projectData?.tenantId,
										});
									}}
								/>
							);
						}
						return '-';
					}}
				</Form.Item>
				<Form.Item formItemKey="reportLevel" label="审计报告等级：" required message="请选择审计报告等级">
					{({ value: reportLevelValue }) => {
						if (mode === 'edit' || reportLevelValue) {
							return (
								<Radio.Group toFormItem>
									{gradeList?.map((grade) => (
										<Radio key={grade?.code} value={grade?.code}>
											{grade?.name}
										</Radio>
									))}
								</Radio.Group>
							);
						}
						return '-';
					}}
				</Form.Item>
				<Form.Item
					formItemKey="reportSummary"
					label="报告摘要："
					rules={{ required: true, whitespace: true, message: '请填写报告摘要' }}
				>
					{({ value: reportSummaryValue }) => {
						if (mode === 'edit' || reportSummaryValue?.length > 0) {
							return (
								<Input.TextArea
									toFormItem
									dispatchChange={['onInput']}
									maxLength={SUMMARY_MAX_LENGTH}
									showCount
									placeholder={SUMMARY_TEXT}
									autosize={{ minRows: 5 }}
								/>
							);
						}
						return '-';
					}}
				</Form.Item>
			</>
		);
	};

	return (
		<div className="project-detail-report">
			<Loading loading={loading}>
				<Form ref={formRef} className="project-detail-report-form" labelWidth="8em" mode={mode}>
					{renderBaseInfoForm()}
					<Form.Item
						className="form-title-label"
						formItemKey="auditConclusion"
						labelPosition="top"
						label="审计结论"
						rules={{ required: true, whitespace: true, message: '请输入审计结论' }}
					>
						{({ value: auditConclusion }) => {
							if (mode === 'edit') {
								return (
									<Input.TextArea
										toFormItem
										dispatchChange={['onInput']}
										maxLength={CONCLUSION_MAX_LENGTH}
										showCount
										placeholder={`输入不超过${CONCLUSION_MAX_LENGTH}字符`}
										autosize={{ minRows: 10 }}
									/>
								);
							}
							return <div className="form-title-indent">{auditConclusion || '-'}</div>;
						}}
					</Form.Item>
					<Form.Item
						className="form-title-label"
						formItemKey="auditProjectOverview"
						labelPosition="top"
						label="审计项目概述"
						rules={[
							{ required: true, whitespace: true, message: '请输入审计项目概述' },
							{
								validator: (config, value, callback) => {
									if (overviewRichTextRef.current?.getTextCnt() > OVERVIEW_MAX_LENGTH) {
										callback(`建议不超过${OVERVIEW_MAX_LENGTH}字符`);
									} else callback();
								},
							},
						]}
					>
						{({ value: auditProjectOverview }) => {
							if (mode === 'edit') {
								return (
									<ParkerRichText
										ref={overviewRichTextRef}
										toFormItem
										placeholder={OVERVIEW_TEXT}
										maxLength={OVERVIEW_MAX_LENGTH}
										showCount
									/>
								);
							}
							return auditProjectOverview ? (
								<ParkerRichText toFormItem className="form-title-indent" />
							) : (
								<div className="form-title-indent">-</div>
							);
						}}
					</Form.Item>
					<Form.Item
						className="form-title-label"
						labelPosition="top"
						label="重点审计发现及整改进度"
						labelWidth="12em"
						formItemKey="problemAndProgressList"
						required
						message="请填写重点审计发现及整改进度"
					>
						<AuditProblemProgress riskGradeList={riskGradeList} ref={progressRef} toFormItem mode={mode} />
					</Form.Item>
					<Form.Item
						className="form-title-label"
						labelPosition="top"
						label="审计发现详述"
						formItemKey="auditProblemDetailList"
						required
						message="请填写审计发现详述"
					>
						<AuditFindingGroup riskGradeList={riskGradeList} ref={findingsRef} toFormItem mode={mode} />
					</Form.Item>
					<Form.Title>附录</Form.Title>
					<Form.Item formItemKey="appendixList" labelWidth={0}>
						<AuditAppendix ref={appendixRef} toFormItem mode={mode} />
					</Form.Item>
					<Form.Item
						className="form-title-label"
						formItemKey="auditConclusionMobile"
						label="移动端展示审计结论"
						labelWidth="12em"
						labelPosition="top"
						rules={{ required: true, whitespace: true, message: '请输入移动端展示审计结论' }}
					>
						{({ value: auditConclusionMobile }) => {
							if (mode === 'edit') {
								return (
									<Input.TextArea
										toFormItem
										dispatchChange={['onInput']}
										maxLength={AUDIT_CONCLUSION_MOBILE_MAX_LENGTH}
										showCount
										placeholder={AUDIT_CONCLUSION_MOBILE_TEXT}
										autosize={{ minRows: 10 }}
									/>
								);
							}
							return <div className="form-title-indent">{auditConclusionMobile || '-'}</div>;
						}}
					</Form.Item>
				</Form>
			</Loading>
		</div>
	);
});

export default ProjectDetailReport;
